package com.bbyb.operating.examination.service.impl;

import com.bbyb.operating.examination.exception.ServiceException;
import com.bbyb.operating.examination.mapper.RoleMapper;
import com.bbyb.operating.examination.mapper.RoleMenuMapper;
import com.bbyb.operating.examination.mapper.RoleUserMapper;
import com.bbyb.operating.examination.model.po.Role;
import com.bbyb.operating.examination.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @ClassName: RoleServiceImpl
 * @Description:
 * @Author: ZengFz
 * @Date: 2024/5/1 11:58:41
 */
@Service
@Slf4j
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RoleUserMapper roleUserMapper;


    /**
     * 新增角色
     *
     * @param role 要新增的角色信息
     * @throws ServiceException 如果角色编码或角色名称为空，或者添加角色失败，则抛出该异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRole(Role role) throws ServiceException {
        try {
            // 检查角色编码和角色名称是否为空
            if (StringUtils.isBlank(role.getRoleCode()) || StringUtils.isBlank(role.getRoleName())) {
                throw new ServiceException("角色编码和角色名称不能为空");
            }

            // 根据角色编码查询角色是否存在
            Role existingRole = roleMapper.selectByRoleCode(role.getRoleCode());
            // 如果角色编码已存在，则抛出异常
            if (existingRole != null) {
                throw new ServiceException("角色编码已存在: " + role.getRoleCode());
            }

            // 插入角色信息
            int affectedRows = roleMapper.insert(role);
            if (affectedRows != 1) {
                throw new ServiceException("添加角色失败，数据库操作失败");
            }
        } catch (Exception e) {
            // 记录异常日志
            log.error("添加角色失败: {}", e.getMessage(), e);
            // 抛出服务异常
            throw new ServiceException("添加角色失败，发生未知错误");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(Integer roleId) throws ServiceException {
        // 参数校验
        if (roleId == null || roleId <= 0) {
            throw new ServiceException("角色ID不能为空且必须大于0");
        }

        // 检查角色是否与其他数据关联
        boolean roleAssociated = isRoleAssociatedWithOtherData(roleId);
        if (roleAssociated) {
            // 如果角色与其他数据关联，抛出自定义异常
            throw new ServiceException("角色与其他数据存在关联，无法删除");
        }

        // 执行删除角色的操作
        try {
            int affectedRows = roleMapper.deleteByPrimaryKey(roleId);
            if (affectedRows != 1) {
                // 删除操作失败，抛出自定义异常
                throw new ServiceException("删除角色失败");
            }
        } catch (Exception e) {
            // 处理数据库异常
            log.error("删除角色失败: {}", e.getMessage(), e);
            throw new ServiceException("删除角色失败，数据库操作异常");
        }
    }

    /**
     * 检查角色是否与其他数据关联
     *
     * @param roleId 角色ID
     * @return 如果角色与其他数据关联，则返回true；否则返回false
     */
    private boolean isRoleAssociatedWithOtherData(Integer roleId) {
        try {
            // 检查角色与菜单的关联
            int menuCount = roleMenuMapper.countByRoleId(roleId);
            // 检查角色与用户的关联
            int userCount = roleUserMapper.countByRoleId(roleId);

            // 如果角色与菜单或用户的关联任何一项存在，则返回true，表示角色与其他数据关联
            return menuCount > 0 || userCount > 0;
        } catch (Exception e) {
            // 处理数据库异常
            log.error("查询角色关联数据失败: {}", e.getMessage(), e);
            return true; // 返回true，表示无法确定角色是否与其他数据关联
        }
    }





}
